<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>components/widget/PatrolMap.vue - Documentation</title>

    <script src="scripts/prettify/prettify.js"></script>
    <script src="scripts/prettify/lang-css.js"></script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>

<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
  <div class="navicon"></div>
</label>

<label for="nav-trigger" class="overlay"></label>

<nav>
    <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Modules</li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-App.html">App</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-Events.html">Events</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-Layout.html">Layout</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#acceptCall">acceptCall</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#acceptPeerVideo">acceptPeerVideo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#callAccepted">callAccepted</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#callFailure">callFailure</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#callSuccessful">callSuccessful</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#clearHTMLVideoStream">clearHTMLVideoStream</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#closePeerVideo">closePeerVideo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#connect">connect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#connectTo">connectTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#dataCloseListenerCB">dataCloseListenerCB</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#dataOpenListenerCB">dataOpenListenerCB</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#getHTMLElements">getHTMLElements</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#handleData">handleData</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#handleRoomOccupantChange">handleRoomOccupantChange</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#loginFailure">loginFailure</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#loginSuccess">loginSuccess</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#onJoystickPositionChange">onJoystickPositionChange</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#performCall">performCall</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#requestFeedFromPeer">requestFeedFromPeer</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#sendData">sendData</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#sendPatrol">sendPatrol</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#setHTMLVideoStream">setHTMLVideoStream</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Layout.html#verifyJoystickState">verifyJoystickState</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-main.html">main</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-Patrol.html">Patrol</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Patrol.html#clearPatrolList">clearPatrolList</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Patrol.html#clearWaypointList">clearWaypointList</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Patrol.html#getSavedPatrols">getSavedPatrols</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Patrol.html#sendPatrol">sendPatrol</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-router.html">router</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-Teleop.html">Teleop</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-Teleop.html#changeJoystickState">changeJoystickState</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-widget_Connection.html">widget/Connection</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Connection.html#connectToPeer">connectToPeer</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Connection.html#disconnectFromPeer">disconnectFromPeer</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Connection.html#handleConnectionChanged">handleConnectionChanged</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Connection.html#handlePeerConnection">handlePeerConnection</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-widget_Joystick.html">widget/Joystick</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#drawBackground">drawBackground</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#drawCanvas">drawCanvas</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#drawJoystick">drawJoystick</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#emitJoystickPosition">emitJoystickPosition</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#findCenterCanvas">findCenterCanvas</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#getCanvasRadius">getCanvasRadius</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#getCenterX">getCenterX</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#getCenterY">getCenterY</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#getJoystickRadius">getJoystickRadius</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#init">init</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#onMouseDown">onMouseDown</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#onMouseMove">onMouseMove</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#onMouseOut">onMouseOut</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#onMouseUp">onMouseUp</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#setCanvasSize">setCanvasSize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_Joystick.html#updateJoystickPositionFromMouseEvent">updateJoystickPositionFromMouseEvent</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html">widget/PatrolMap</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#addWaypointCoord">addWaypointCoord</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#adjustCanvasToVideo">adjustCanvasToVideo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#drawCanvas">drawCanvas</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#drawWaypoint">drawWaypoint</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#drawWaypointList">drawWaypointList</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#drawYawArrow">drawYawArrow</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#getCanvasCoordinatesFromVideo">getCanvasCoordinatesFromVideo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#getVideoCoordinatesOfEvent">getVideoCoordinatesOfEvent</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#getVideoOffsetAndScale">getVideoOffsetAndScale</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#init">init</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#isClickValid">isClickValid</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#onMouseDown">onMouseDown</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#onMouseMove">onMouseMove</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#onMouseOut">onMouseOut</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#onMouseUp">onMouseUp</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_PatrolMap.html#updateWaypoint">updateWaypoint</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-widget_SaveLoad.html">widget/SaveLoad</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_SaveLoad.html#addPatrolToPatrolList">addPatrolToPatrolList</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_SaveLoad.html#removePatrolFromList">removePatrolFromList</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_SaveLoad.html#selectPatrolFromList">selectPatrolFromList</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-widget_VideoBox.html">widget/VideoBox</a></span></li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-widget_WaypointTable.html">widget/WaypointTable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="module-widget_WaypointTable.html#removeWaypointFromList">removeWaypointFromList</a></span></li>
</nav>

<div id="main">
    
    <h1 class="page-title">components/widget/PatrolMap.vue</h1>
    

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>&lt;template>
  &lt;!-- Patrol Map widget -->
  &lt;div class="h-100 w-100 position-relative">
    &lt;!-- Video Box -->
    &lt;video-box
      :show="true"
      :video-id="patrolMapId"
      class="w-100 h-100 position-absolute"
      style="top:0;left:0;" />
    &lt;!-- Canvas -->
    &lt;canvas
      ref="canvas"
      class="w-100 h-100 position-absolute"
      style="top:0;left:0;z-index:10;"
      @mousedown="onMouseDown"
      @mousemove="onMouseMove"
      @mouseup="onMouseUp"
      @mouseout="onMouseOut" />
  &lt;/div>
&lt;/template>

&lt;script>
/**
 * Vue SFC used as a widget to set waypoint on a map. This component
 * uses the VideoBox component to show the robot map (that is sent from
 * the robot in a video feed format) and put a canvas on top of it to
 * detect user clicks. When a click is detected the x and y position
 * is used to set a waypoint in the array given in props (push). The
 * canvas then read the array and draw waypoint on the map where the
 * user clicked previously.
 * This component have the following dependency :
 * VideoBox.vue Component and Bootstrap-Vue for styling.
 *
 *
 * @module widget/PatrolMap
 * @vue-prop {Object[]} waypointList - Lists the current waypoints
 * @vue-prop {String} patrolMapId - Identifies map source with exact name reference
 * @vue-data {Object} videoElement - Contains reference to video-id
 * @vue-data {Object} canvas - Contains reference to responsive overlay of map
 * @vue-data {Object} context - Sets canvas context
 * @vue-data {Number} CanvasRefreshRate - Sets the constant refresh rate of the displayed canvas
 * @vue-data {Object} loopIntervalId - Contains refresh rate and display parameter of the map
 * @vue-data {Boolean} enable - Enables or disables the display of the map and canvas
 */

/* Disabled comment documentation
 * Might use those eventually by forking jsdoc-vue-js so it can manage the author
 * and version tag correctly
 * @author Valerie Gauthier &lt;valerie.gauthier@usherbrooke.ca>
 * @author Edouard Legare &lt;edouard.legare@usherbrooke.ca>
 * @version 1.0.0
 */

import VideoBox from './VideoBox';

export default {
  name: 'patrol-map',
  components: {
    VideoBox,
  },
  props: {
    waypointList: {
      type: Array,
      default: () => [],
      required: true,
    },
    patrolMapId: {
      type: String,
      required: true,
    },
  },
  data() {
    return {
      videoElement: null,
      canvas: null,
      context: null,
      CanvasRefreshRate: 60.0, // Hz
      isMouseDown: false,
      loopIntervalId: null,
      enable: true,
    };
  },
  /**
   * Lifecycle Hook - mounted.
   * On component mounted, Get html elements and initialize.
   * @method
   * @listens mount(el)
   */
  mounted() {
    this.videoElement = document.getElementById(this.patrolMapId);
    this.canvas = this.$refs.canvas;
    this.context = this.canvas.getContext('2d');
    this.init();
  },
  /**
   * Lifecycle Hook - destroyed.
   * On component destroyed, clear refresh rate of canvas.
   * @method
   * @listens destroyed(el)
   */
  destroyed() {
    clearInterval(this.loopIntervalId);
  },
  methods: {
    /**
     * Initialisation of canvas refrash rate and call to canvas resizing functions.
     * @method
     */
    init() {
      this.loopIntervalId = setInterval(() => {
        if (this.enable) {
          this.adjustCanvasToVideo();
          this.drawCanvas();
        }
      }, 1000 / this.CanvasRefreshRate);
    },

    /**
     * Clears canvas and redraws the waypoints of the current patrol.
     * @method
     */
    drawCanvas() {
      this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
      this.drawWaypointList();
    },

    /**
     * Calls for the drawing the waypoints with corresponding arrows (indicating the yaws) of
     * each waypoint of the current waypoint list.
     * @method
     */
    drawWaypointList() {
      for (const [index, wp] of this.waypointList.entries()) {
        this.drawWaypoint(wp, index);
        this.drawYawArrow(wp);
      }
    },

    /**
     * Draws a waypoint on the canvas.
     * @method
     * @param {Object} wp - Waypoint
     * @param {Number} wp.x - Waypoint's x coordinate in pixel
     * @param {Number} wp.y - Waypoint's y coordinate in pixel
     * @param {Number} index - Index number of sent waypoint
     */
    drawWaypoint(wp, index) {
      const wpColor = '#00FF00';
      const coord = this.getCanvasCoordinatesFromVideo(wp.x, wp.y);

      const wpRadius = 7;
      this.context.beginPath();
      this.context.arc(coord.x, coord.y, wpRadius, 0, 2 * Math.PI);
      this.context.fillStyle = wpColor;
      this.context.fill();

      this.context.font = '20px serif';
      this.context.fillStyle = '#000000';
      this.context.fillText(index + 1, coord.x + 8, coord.y + 8, 25);
    },

    /**
     * Draws arrow for the yaw of the waypoint on the canvas.
     * @method
     * @param {Object} wp - Waypoint
     * @param {Number} wp.x - Waypoint's x coordinate in pixel
     * @param {Number} wp.y - Waypoint's y coordinate in pixel
     * @param {Number} wp.yaw - Waypoint's yaw angle in radians
     */
    drawYawArrow(wp) {
      const arrowColor = '#00FF00';
      const coord = this.getCanvasCoordinatesFromVideo(wp.x, wp.y);

      const arrowLength = Math.min(this.canvas.width, this.canvas.height) / 15;
      const headLength = arrowLength / 4;
      const radYaw = -wp.yaw / 180 * Math.PI;
      const arrowEnd = {
        x: coord.x + arrowLength * Math.cos(radYaw),
        y: coord.y + arrowLength * Math.sin(radYaw),
      };
      const arrowTip1 = {
        x: arrowEnd.x - headLength * Math.cos(radYaw - Math.PI / 4),
        y: arrowEnd.y - headLength * Math.sin(radYaw - Math.PI / 4),
      };
      const arrowTip2 = {
        x: arrowEnd.x - headLength * Math.cos(radYaw + Math.PI / 4),
        y: arrowEnd.y - headLength * Math.sin(radYaw + Math.PI / 4),
      };

      this.context.lineCap = 'round';
      this.context.lineWidth = Math.max(1, arrowLength / 10);
      this.context.strokeStyle = arrowColor;

      this.context.beginPath();
      this.context.moveTo(coord.x, coord.y);
      this.context.lineTo(arrowEnd.x, arrowEnd.y);
      this.context.stroke();

      this.context.beginPath();
      this.context.moveTo(arrowEnd.x, arrowEnd.y);
      this.context.lineTo(arrowTip1.x, arrowTip1.y);
      this.context.stroke();

      this.context.beginPath();
      this.context.moveTo(arrowEnd.x, arrowEnd.y);
      this.context.lineTo(arrowTip2.x, arrowTip2.y);
      this.context.stroke();
    },

    /**
     * Get position/coordinate of mouse event on video.
     * @method
     * @param {HTMLElement} - Event given by the click.
     * @returns {Object} X and Y coordinate in pixels of event (mouse position).
     */
    getVideoCoordinatesOfEvent(event) {
      const offsetAndScale = this.getVideoOffsetAndScale();
      const rect = this.videoElement.getBoundingClientRect();
      const x = (event.clientX - rect.left - offsetAndScale.offsetX) / offsetAndScale.scale;
      const y = (event.clientY - rect.top - offsetAndScale.offsetY) / offsetAndScale.scale;
      return {
        x,
        y,
      };
    },

    /**
     * Sets canvas size (height and width) to match the size of the video.
     * @method
     */
    adjustCanvasToVideo() {
      this.canvas.width = this.videoElement.offsetWidth;
      this.canvas.height = this.videoElement.offsetHeight;
    },

    /**
     * Compute the offset and rescaling parameters of resized video from original content.
     * @method
     * @returns {Object} Offset in X, offset in Y and scaling ratios.
     */
    getVideoOffsetAndScale() {
      const videoRatio = this.videoElement.videoWidth / this.videoElement.videoHeight;

      let offsetX = 0;
      let offsetY = 0;
      let scale = 1;
      if ((this.videoElement.offsetHeight * videoRatio) > this.videoElement.offsetWidth) {
        scale = this.videoElement.osffsetWidth / this.videoElement.videoWidth;
        offsetY = (this.videoElement.offsetHeight - (this.videoElement.videoHeight * scale)) / 2;
      } else {
        scale = this.videoElement.offsetHeight / this.videoElement.videoHeight;
        offsetX = (this.videoElement.offsetWidth - (this.videoElement.videoWidth * scale)) / 2;
      }
      return {
        offsetX,
        offsetY,
        scale,
      };
    },

    /**
     * Corrects the waypoint coordinate (x,y) from the offsets and scale parameters of video.
     * @method
     * @param {Number} x - Horizontal coordinate on canvas.
     * @param {Number} y - Vertical coordinate on canvas.
     * @returns {Object} - X and Y coordinate in pixels of event (mouse position).
     */
    getCanvasCoordinatesFromVideo(x, y) {
      const offsetAndScale = this.getVideoOffsetAndScale();

      return {
        x: (x * offsetAndScale.scale) + offsetAndScale.offsetX,
        y: (y * offsetAndScale.scale) + offsetAndScale.offsetY,
      };
    },

    /**
     * CallBack of mouse down event. Verify validity and initialise waypoint creation.
     * @method
     * @param {HTMLElement} event - Event element given by the click.
     */
    onMouseDown(event) {
      if (event.button === 0) {
        const coord = this.getVideoCoordinatesOfEvent(event);
        if (this.isClickValid(coord)) {
          const wp = coord;
          wp.yaw = 0;
          this.addWaypointCoord(wp);
        }
      }
      this.isMouseDown = true;
    },

    /**
     * Callback of mouse move event. Updates the yaw with mouse position.
     * @method
     * @param {HTMLElement} event - Event given by mouse move.
     */
    onMouseMove(event) {
      if (this.isMouseDown) {
        console.log('MouseMoved');
        const wp = this.waypointList[this.waypointList.length - 1];
        const mousePosition = this.getVideoCoordinatesFromEvent(event);
        wp.yaw = -Math.atan2(mousePosition.y - wp.y, mousePosition.x - wp.x) * 180 / Math.PI;
        this.updateWaypoint(wp);
      }
    },

    /**
     * Callback of mouse up event, finalize the waypoint creation process.
     * @method
     * @param {HTMLElement} event - Event element given by the click.
     */
    onMouseUp(event) {
      if (this.isMouseDown) {
        // Write waypoint to list of waypoints
        console.log('MouseUP');
        const date = new Date();
        const wp = this.waypointList[this.waypointList.length - 1];
        const coord = this.getVideoCoordinatesFromEvent(event);

        wp.yaw = -Math.atan2(coord.y - wp.y, coord.x - wp.x) * 180 / Math.PI;
        wp.dateTime = date.getTime();
        this.updateWaypoint(wp);
        this.isMouseDown = false;
      }
    },

    /**
     * Callback of mouse out event, terminate the waypoint creation.
     * @method
     * @param {HTMLElement} event - Event element given by the click.
     */
    onMouseOut(event) {
      if (this.isMouseDown) {
        console.log('MouseOut');
        this.waypointList.pop();
        this.isMouseDown = false;
      }
    },

    /**
     * Adds a waypoint to the list of current waypoints.
     * @method
     * @param {Object} wp - Waypoint.
     */
    addWaypointCoord(wp) {
      this.waypointList.push(wp);
    },

    /**
     * Updates last waypoint of the waypoint list.
     * @method
     * @param {Object} wp - Waypoint.
     */
    updateWaypoint(wp) {
      this.waypointList.pop();
      this.waypointList.push(wp);
    },

    /**
     * Check to see if element is in bound.
     * @method
     * @param {Object} coord - Coordinates of an element.
     * @param {Number} coord.x - X coordinate of element.
     * @param {Number} coord.y - Y coordinate of element.
     * @returns {boolean} true if coordinates of the element are in bounds of the video.
     */
    isClickValid(coord) {
      return coord.x >= 0
        &amp;&amp; coord.x &lt; this.videoElement.videoWidth
        &amp;&amp; coord.y >= 0
        &amp;&amp; coord.y &lt; this.videoElement.videoHeight;
    },
  },
};
&lt;/script>

&lt;style>
&lt;/style>
</code></pre>
        </article>
    </section>




</div>

<br class="clear">

<footer>
    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Fri Apr 26 2019 14:20:12 GMT-0400 (Eastern Daylight Time) using the Minami theme.
</footer>

<script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script>
</body>
</html>
